package com.sojson.service.impl;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.sojson.config.exception.TransException;
import com.sojson.constant.Lock;
import com.sojson.dao.ActivityDao;
import com.sojson.dao.CouponDao;
import com.sojson.dao.CouponGoodsDao;
import com.sojson.dao.CouponModuleDao;
import com.sojson.dao.CouponStoreDao;
import com.sojson.dao.UserCouponDao;
import com.sojson.entity.bo.CouponUseGoodsParam;
import com.sojson.entity.bo.CouponUseParam;
import com.sojson.entity.po.Activity;
import com.sojson.entity.po.Coupon;
import com.sojson.entity.po.CouponModule;
import com.sojson.entity.po.CouponStore;
import com.sojson.entity.po.UserActivity;
import com.sojson.entity.po.UserCoupon;
import com.sojson.entity.vo.CouponGoodsVo;
import com.sojson.entity.vo.UserCouponVo;
import com.sojson.enums.core.ECouponEnable;
import com.sojson.enums.core.ECouponScopeGoods;
import com.sojson.enums.core.ECouponScopeModule;
import com.sojson.enums.core.ECouponScopeStore;
import com.sojson.enums.core.ECouponStatus;
import com.sojson.enums.core.ECouponTypeScope;
import com.sojson.enums.core.EUserCouponStatus;
import com.sojson.service.ActivityService;
import com.sojson.service.CouponService;
import com.sojson.service.UserActivityService;
import com.sojson.service.UserCouponService;
import com.sojson.util.DateUtil;
import com.sojson.util.StringUtil;
import com.sojson.util.token.TokenUtil;

/**
 * 用户优惠券Service实现类
 * 
 * @author liu
 * @date 2021-06-02
 */
@Service
public class UserCouponServiceImpl implements UserCouponService {

    @Autowired
    private UserCouponServiceImpl userCouponServiceImpl;
    @Autowired
    private ActivityService activityService;
    @Autowired
    private CouponService couponService;
    @Autowired
    private UserActivityService userActivityService;
    @Resource
    private UserCouponDao userCouponDaoImpl;
    @Resource
    private ActivityDao activityDaoImpl;
    @Resource
    private CouponDao couponDaoImpl;
    @Resource
    private CouponModuleDao couponModuleDaoImpl;
    @Resource
    private CouponStoreDao couponStoreDaoImpl;
    @Resource
    private CouponGoodsDao couponGoodsDaoImpl;

    /**
     * 单条插入
     * 
     * @param userCoupon
     * @return
     */
    @Override
    public int insert(UserCoupon userCoupon) {
        int insert = userCouponDaoImpl.insert(userCoupon);
        return insert;
    }

    /**
     * 批量插入
     * 
     * @param userCoupon
     * @return
     */
    @Override
    public int insertList(UserCoupon userCoupon) {
        int insertList = userCouponDaoImpl.insertList(userCoupon.getUserCoupons());
        return insertList;
    }

    /**
     * 通过对象批量删除(物理删除)
     * 
     * @param userCoupon
     * @return
     */
    @Override
    public int deleteByDto(UserCoupon userCoupon) {
        int deleteByDto = userCouponDaoImpl.deleteByDto(userCoupon);
        return deleteByDto;
    }

    /**
     * 统计全部数量
     * 
     * @return
     */
    @Override
    public int countAll() {
        int countAll = userCouponDaoImpl.countAll();
        return countAll;
    }

    /**
     * 查询所有
     * 
     * @return
     */
    @Override
    public List<UserCoupon> listAll() {
        List<UserCoupon> findAll = userCouponDaoImpl.listAll();
        return findAll;
    }

    /**
     * 根据对象统计数量
     * 
     * @param userCoupon
     * @return
     */
    @Override
    public int countByDto(UserCoupon userCoupon) {
        int countByDto = userCouponDaoImpl.countByDto(userCoupon);
        return countByDto;
    }

    /**
     * 根据对象查询
     * 
     * @param userCoupon
     * @return
     */
    @Override
    public List<UserCoupon> listByDto(UserCoupon userCoupon) {
        List<UserCoupon> findByDto = userCouponDaoImpl.listByDto(userCoupon);
        return findByDto;
    }

    /**
     * 通过id删除(物理删除)
     * 
     * @param id
     * @return
     */
    @Override
    public int deleteById(Integer id) {
        int deleteById = userCouponDaoImpl.deleteById(id);
        return deleteById;
    }

    /**
     * 通过id数组删除(物理删除)
     * 
     * @param ids
     * @return
     */
    @Override
    public int deleteByIds(Integer[] ids) {
        int deleteByIds = userCouponDaoImpl.deleteByIds(ids);
        return deleteByIds;
    }

    /**
     * 通过id更新(全部更新)
     * 
     * @param userCoupon
     * @return
     */
    @Override
    public int updateAllById(UserCoupon userCoupon) {
        int updateAllById = userCouponDaoImpl.updateAllById(userCoupon);
        return updateAllById;
    }

    /**
     * 通过id列表更新(全部更新)(更新内容相同)
     * 
     * @param userCoupon
     * @return
     */
    @Override
    public int updateAllByIdList(UserCoupon userCoupon) {
        int updateAllByIdList = userCouponDaoImpl.updateAllByIdList(userCoupon);
        return updateAllByIdList;
    }

    /**
     * 通过id列表更新(全部更新)(更新内容不相同)
     * 
     * @param userCoupon
     * @return
     */
    @Override
    public int updateDtoListAllById(UserCoupon userCoupon) {
        int updateDtoListAllById = userCouponDaoImpl.updateDtoListAllById(userCoupon.getUserCoupons());
        return updateDtoListAllById;
    }

    /**
     * 通过id更新(局部更新)
     * 
     * @param userCoupon
     * @return
     */
    @Override
    public int updateById(UserCoupon userCoupon) {
        int updateById = userCouponDaoImpl.updateById(userCoupon);
        return updateById;
    }

    /**
     * 通过id列表更新(局部更新)(更新内容相同)
     * 
     * @param userCoupon
     * @return
     */
    @Override
    public int updateByIdList(UserCoupon userCoupon) {
        int updateByIdList = userCouponDaoImpl.updateByIdList(userCoupon);
        return updateByIdList;
    }

    /**
     * 通过id列表更新(局部更新)(更新内容不相同)
     * 
     * @param userCoupon
     * @return
     */
    @Override
    public int updateDtoListById(UserCoupon userCoupon) {
        int updateDtoListById = userCouponDaoImpl.updateDtoListById(userCoupon.getUserCoupons());
        return updateDtoListById;
    }

    /**
     * 通过id查询
     * 
     * @param id
     * @return
     */
    @Override
    public UserCoupon findById(Integer id) {
        UserCoupon findById = userCouponDaoImpl.findById(id);
        return findById;
    }

    /**
     * 通过id数组查询
     * 
     * @param ids
     * @return
     */
    @Override
    public List<UserCoupon> findByIds(Integer[] ids) {
        List<UserCoupon> findByIds = userCouponDaoImpl.findByIds(ids);
        return findByIds;
    }

    /**
     * 通过对象查询id列表
     * 
     * @param userCoupon
     * @return
     */
    @Override
    public List<Integer> findIdByDto(UserCoupon userCoupon) {
        List<Integer> findIdByDto = userCouponDaoImpl.findIdByDto(userCoupon);
        return findIdByDto;
    }

    /**
     * 通过no删除(物理删除)
     * 
     * @param no
     * @return
     */
    @Override
    public int deleteByNo(String no) {
        int deleteByNo = userCouponDaoImpl.deleteByNo(no);
        return deleteByNo;
    }

    /**
     * 通过no数组删除(物理删除)
     * 
     * @param nos
     * @return
     */
    @Override
    public int deleteByNos(String[] nos) {
        int deleteByNos = userCouponDaoImpl.deleteByNos(nos);
        return deleteByNos;
    }

    /**
     * 通过no更新(全部更新)
     * 
     * @param userCoupon
     * @return
     */
    @Override
    public int updateAllByNo(UserCoupon userCoupon) {
        int updateAllByNo = userCouponDaoImpl.updateAllByNo(userCoupon);
        return updateAllByNo;
    }

    /**
     * 通过no列表更新(全部更新)(更新内容相同)
     * 
     * @param userCoupon
     * @return
     */
    @Override
    public int updateAllByNoList(UserCoupon userCoupon) {
        int updateAllByNoList = userCouponDaoImpl.updateAllByNoList(userCoupon);
        return updateAllByNoList;
    }

    /**
     * 通过no列表更新(全部更新)(更新内容不相同)
     * 
     * @param userCoupon
     * @return
     */
    @Override
    public int updateDtoListAllByNo(UserCoupon userCoupon) {
        int updateDtoListAllByNo = userCouponDaoImpl.updateDtoListAllByNo(userCoupon.getUserCoupons());
        return updateDtoListAllByNo;
    }

    /**
     * 通过no更新(局部更新)
     * 
     * @param userCoupon
     * @return
     */
    @Override
    public int updateByNo(UserCoupon userCoupon) {
        int updateByNo = userCouponDaoImpl.updateByNo(userCoupon);
        return updateByNo;
    }

    /**
     * 通过no列表更新(局部更新)(更新内容相同)
     * 
     * @param userCoupon
     * @return
     */
    @Override
    public int updateByNoList(UserCoupon userCoupon) {
        int updateByNoList = userCouponDaoImpl.updateByNoList(userCoupon);
        return updateByNoList;
    }

    /**
     * 通过no列表更新(局部更新)(更新内容不相同)
     * 
     * @param userCoupons
     * @return
     */
    @Override
    public int updateDtoListByNo(UserCoupon userCoupon) {
        int updateDtoListByNo = userCouponDaoImpl.updateDtoListByNo(userCoupon.getUserCoupons());
        return updateDtoListByNo;
    }

    /**
     * 通过no查询
     * 
     * @param no
     * @return
     */
    @Override
    public UserCoupon findByNo(String no) {
        UserCoupon findByNo = userCouponDaoImpl.findByNo(no);
        return findByNo;
    }

    /**
     * 通过no数组查询
     * 
     * @param nos
     * @return
     */
    @Override
    public List<UserCoupon> findByNos(String[] nos) {
        List<UserCoupon> findByNos = userCouponDaoImpl.findByNos(nos);
        return findByNos;
    }

    /**
     * 通过对象查询no列表
     * 
     * @param userCoupon
     * @return
     */
    @Override
    public List<String> findNoByDto(UserCoupon userCoupon) {
        List<String> findNoByDto = userCouponDaoImpl.findNoByDto(userCoupon);
        return findNoByDto;
    }

    /**
     * 清空数据(物理清空)
     */
    @Override
    public int clear() {
        return userCouponDaoImpl.clear();
    }

    /**
     * 领取优惠券
     * 
     * @param couponId
     * @return
     * @throws Exception 
     */
    @Override
    public int addCoupon(Integer couponId) throws Exception {
        int insert = 0;
        Date nowDate = DateUtil.nowDate();

        synchronized (Lock.UPDATE_COUPON_NUMBER) {
            synchronized (Lock.ADD_COUPON) {
                // 查询活动信息
                Coupon findById = couponDaoImpl.findById(couponId);
                if (StringUtil.isBlankObject(findById)) {
                    throw new TransException("优惠券不存在！");
                }

                // 判断活动是否进行中
                couponService.isUnderway(findById, nowDate.getTime());

                // 判断用户是否满足活动条件
                couponService.isCanTakePartIn(findById);

                // 领取优惠券
                insert = userCouponServiceImpl.addCouponGo(findById, nowDate);
            }
        }
        return insert;
    }

    @Transactional
    public int addCouponGo(Coupon coupon, Date nowDate) throws Exception {
        int insert = 0;

        // 领取优惠券(添加数据)
        UserCoupon userCoupon = new UserCoupon();
        userCoupon.insertInit(coupon, nowDate);
        userCoupon.setUserNo(TokenUtil.getUserNo());
        // 插入数据
        insert = userCouponServiceImpl.insert(userCoupon);
        if (insert < 1) {
            throw new TransException("领取失败，请重试！");
        }

        Coupon c = new Coupon();
        c.setNo(coupon.getNo());
        c.setNumber(coupon.getNumber() - 1);
        int updateByNo = couponDaoImpl.updateByNo(c);
        if (updateByNo != insert) {
            throw new TransException("领取失败，请重试！");
        }

        return insert;
    }

    /**
     * 活动领取优惠券
     * 
     * @param activityId
     * @return
     * @throws Exception 
     */
    @Override
    public int addCouponByActivity(Integer activityId) throws Exception {
        int insert = 0;
        Date nowDate = DateUtil.nowDate();
        // 查询活动信息
        Activity findById = activityDaoImpl.findById(activityId);
        if (StringUtil.isBlankObject(findById)) {
            throw new TransException("活动不存在！");
        }

        // 判断用户是否满足活动条件
        activityService.isCanTakePartIn(findById);

        synchronized (Lock.UPDATE_COUPON_NUMBER) {
            synchronized (Lock.ADD_COUPON_ACTIVITY) {
                // 获取优惠券信息
                List<Coupon> findByNos = couponDaoImpl.findByNos(findById.getBindCouponNo().split(","));

                // 判断活动是否进行中
                activityService.activityIsUnderway(findById, findByNos, nowDate.getTime());

                // 判断用户是否满足活动条件
                activityService.isCanTakePartIn(findByNos, findById);

                // 判断优惠券是否可以领取
                isCanGet(findByNos, findById);

                // 领取优惠券
                userCouponServiceImpl.addCouponByActivityGo(findById, findByNos, nowDate);
            }
        }
        return insert;
    }

    @Transactional
    public int addCouponByActivityGo(Activity activity, List<Coupon> coupons, Date date) throws Exception {
        int insert = 0;

        // 添加参与活动记录
        UserActivity userActivity = new UserActivity();
        userActivity.insertInit(activity, date);
        userActivity.setUserNo(TokenUtil.getUserNo());
        insert = userActivityService.insert(userActivity);
        if (insert < 1) {
            throw new TransException("领取失败，请重试！");
        }

        // 领取优惠券(添加数据)
        List<UserCoupon> arrayList = new ArrayList<>();
        String userNo = TokenUtil.getUserNo();
        for (Coupon coupon : coupons) {
            UserCoupon userCoupon = new UserCoupon();
            userCoupon.insertInit(coupon, date);
            userCoupon.setActivityNo(activity.getNo());
            userCoupon.setUserNo(userNo);
            arrayList.add(userCoupon);
        }
        // 插入数据
        insert = userCouponDaoImpl.insertList(arrayList);
        if (insert < 1) {
            throw new TransException("领取失败，请重试！");
        }

        // 修改优惠券数量
        List<Coupon> couponList = new ArrayList<>();
        for (Coupon coupon : coupons) {
            Coupon c = new Coupon();
            c.setNo(coupon.getNo());
            c.setNumber(coupon.getNumber() - 1);
            couponList.add(c);
        }
        int updateDtoListByNo = couponDaoImpl.updateDtoListByNo(couponList);
        if (insert != updateDtoListByNo) {
            throw new TransException("领取失败，请重试！");
        }

        return insert;
    }

    /**
     * 判断优惠券是否可以领取
     * 
     * @param activity
     * @throws SQLException 
     */
    public void isCanGet(List<Coupon> coupons, Activity activity) throws SQLException {
        // 判断优惠券状态
        long currentTimeMillis = System.currentTimeMillis();
        for (Coupon coupon : coupons) {
            if (ECouponStatus.YES_LAUNCH.getCode() != coupon.getStatus()
                || currentTimeMillis < coupon.getStartDate().getTime()
                || currentTimeMillis > coupon.getEndDate().getTime()) {
                throw new TransException("此优惠券已被商家关闭领取或不在领取时间！");
            }
        }
    }

    /**
     * 获取优惠券
     * 
     * @param userCoupon
     * @return
     * @throws Exception 
     */
    @Override
    public List<UserCouponVo> listSimple(UserCouponVo userCoupon) {
        return userCouponDaoImpl.listSimple(userCoupon);
    }

    /**
     * 根据对象查询
     * 
     * @param couponUse
     * @return
     */
    @Override
    public List<UserCouponVo> list(CouponUseParam couponUse) {
        // 优惠券列表
        List<UserCouponVo> list = userCouponDaoImpl.list(couponUse);

        // 查询此商品是否可用
        Integer enable = couponUse.getEnable();
        if (enable == ECouponEnable.ALL_LABEL_GOODS.getCode()) {
            Boolean isValid = couponUse.getIsValid();
            Boolean isShop = couponUse.getIsShop();
            Date thisTime = couponUse.getThisTime();
            String useModuleNo = couponUse.getUseModuleNo();
            String useStoreNo = couponUse.getUseStoreNo();
            String useGoodsNo = couponUse.getUseGoodsNo();
            List<CouponUseGoodsParam> couponUseGoodss = couponUse.getCouponUseGoodss();
            for (UserCouponVo userCouponVo : list) {
                Coupon coupon = userCouponVo.getCoupon();
                String no = coupon.getNo();
                Integer typeScope = coupon.getTypeScope();
                if (!isValid) {
                    if (coupon.getStatus() != ECouponStatus.YES_LAUNCH.getCode()
                        || userCouponVo.getStatus() != EUserCouponStatus.USE_NO.getCode()) {
                        userCouponVo.setIsEnable(false);
                        continue;
                    }
                    if (StringUtil.isNotBlankObject(thisTime)) {
                        long time = thisTime.getTime();
                        if (coupon.getStartDate().getTime() > time || coupon.getEndDate().getTime() < time) {
                            userCouponVo.setIsEnable(false);
                            continue;
                        }
                    }
                }
                if (typeScope == ECouponTypeScope.CUSTOM_SCOPE.getCode()) {
                    Integer scopeModule = coupon.getScopeModule();
                    if (ECouponScopeModule.APPOINT.getCode() == scopeModule
                        && !coupon.getUseModuleNo().equals(useModuleNo)) {
                        userCouponVo.setIsEnable(false);
                        continue;
                    } else if (ECouponScopeModule.APPOINT_SOME_YES.getCode() == scopeModule
                        || ECouponScopeModule.APPOINT_SOME_NO.getCode() == scopeModule) {
                        CouponModule couponModule = new CouponModule();
                        couponModule.setCouponNo(no);
                        couponModule.setModuleNo(useModuleNo);
                        int countByDto = couponModuleDaoImpl.countByDto(couponModule);
                        if (ECouponScopeModule.APPOINT_SOME_YES.getCode() == scopeModule && countByDto < 1) {
                            userCouponVo.setIsEnable(false);
                            continue;
                        } else if (ECouponScopeModule.APPOINT_SOME_NO.getCode() == scopeModule && countByDto > 0) {
                            userCouponVo.setIsEnable(false);
                            continue;
                        }
                    }
                    Integer scopeStore = coupon.getScopeStore();
                    if (ECouponScopeStore.APPOINT.getCode() == scopeStore
                        && !coupon.getUseStoreNo().equals(useStoreNo)) {
                        userCouponVo.setIsEnable(false);
                        continue;
                    } else if (ECouponScopeStore.APPOINT_SOME_YES.getCode() == scopeStore
                        || ECouponScopeStore.APPOINT_SOME_NO.getCode() == scopeStore) {
                        CouponStore couponStore = new CouponStore();
                        couponStore.setCouponNo(no);
                        couponStore.setStoreNo(useStoreNo);
                        int countByDto = couponStoreDaoImpl.countByDto(couponStore);
                        if (ECouponScopeStore.APPOINT_SOME_YES.getCode() == scopeStore && countByDto < 1) {
                            userCouponVo.setIsEnable(false);
                            continue;
                        } else if (ECouponScopeStore.APPOINT_SOME_NO.getCode() == scopeStore && countByDto > 0) {
                            userCouponVo.setIsEnable(false);
                            continue;
                        }
                    }
                    Integer scopeGoods = coupon.getScopeGoods();
                    if (ECouponScopeGoods.APPOINT.getCode() == scopeGoods) {
                        if (isShop || !coupon.getUseGoodsNo().equals(useGoodsNo)) {
                            userCouponVo.setIsEnable(false);
                            continue;
                        }
                    } else if (ECouponScopeGoods.APPOINT_SOME_YES.getCode() == scopeGoods
                        || ECouponScopeGoods.APPOINT_SOME_NO.getCode() == scopeGoods) {
                        int size = 0;
                        int countByDto = 0;
                        CouponGoodsVo couponGoods = new CouponGoodsVo();
                        couponGoods.setCouponNo(no);

                        if (isShop) {
                            couponGoods.setCouponUseGoodss(couponUseGoodss);
                            countByDto = couponGoodsDaoImpl.countCoupon(couponGoods);
                        } else {
                            couponGoods.setGoodsNo(useGoodsNo);
                            countByDto = couponGoodsDaoImpl.countByDto(couponGoods);
                        }
                        if (ECouponScopeGoods.APPOINT_SOME_YES.getCode() == scopeGoods && countByDto < size) {
                            userCouponVo.setIsEnable(false);
                            continue;
                        } else if (ECouponScopeGoods.APPOINT_SOME_NO.getCode() == scopeGoods && countByDto > 0) {
                            userCouponVo.setIsEnable(false);
                            continue;
                        }
                    }
                } else if (typeScope == ECouponTypeScope.APPOINT_MODULE.getCode()) {
                    if (!coupon.getUseModuleNo().equals(useModuleNo)) {
                        userCouponVo.setIsEnable(false);
                        continue;
                    }
                } else if (typeScope == ECouponTypeScope.APPOINT_STORE.getCode()) {
                    if (!coupon.getUseStoreNo().equals(useStoreNo)) {
                        userCouponVo.setIsEnable(false);
                        continue;
                    }
                } else if (typeScope == ECouponTypeScope.APPOINT_GOODS.getCode()) {
                    if (isShop) {
                        userCouponVo.setIsEnable(false);
                        continue;
                    } else if (!coupon.getUseGoodsNo().equals(useGoodsNo)) {
                        userCouponVo.setIsEnable(false);
                        continue;
                    }
                }
                userCouponVo.setIsEnable(true);
            }
        }
        return list;
    }

    /**
     * 根据对象查询
     * 
     * @param couponUse
     * @return
     * @throws SQLException
     */
    @Override
    public List<UserCouponVo> listShopping(CouponUseParam couponUse) {
        // 优惠券列表
        List<UserCouponVo> list = userCouponDaoImpl.listShopping(couponUse);

        // 查询此商品是否可用
        Integer enable = couponUse.getEnable();
        if (enable == ECouponEnable.ALL_LABEL_GOODS.getCode()) {
            Boolean isValid = couponUse.getIsValid();
            Date thisTime = couponUse.getThisTime();
            String useModuleNo = couponUse.getUseModuleNo();
            String useStoreNo = couponUse.getUseStoreNo();
            List<CouponUseGoodsParam> couponUseGoodss = couponUse.getCouponUseGoodss();
            for (UserCouponVo userCouponVo : list) {
                Coupon coupon = userCouponVo.getCoupon();
                String no = coupon.getNo();
                Integer typeScope = coupon.getTypeScope();
                if (!isValid) {
                    if (coupon.getStatus() != ECouponStatus.YES_LAUNCH.getCode()
                        || userCouponVo.getStatus() != EUserCouponStatus.USE_NO.getCode()) {
                        userCouponVo.setIsEnable(false);
                        continue;
                    }
                    if (StringUtil.isNotBlankObject(thisTime)) {
                        long time = thisTime.getTime();
                        if (coupon.getStartDate().getTime() > time || coupon.getEndDate().getTime() < time) {
                            userCouponVo.setIsEnable(false);
                            continue;
                        }
                    }
                }
                if (typeScope == ECouponTypeScope.CUSTOM_SCOPE.getCode()) {
                    Integer scopeModule = coupon.getScopeModule();
                    if (ECouponScopeModule.APPOINT.getCode() == scopeModule
                        && !coupon.getUseModuleNo().equals(useModuleNo)) {
                        userCouponVo.setIsEnable(false);
                        continue;
                    } else if (ECouponScopeModule.APPOINT_SOME_YES.getCode() == scopeModule
                        || ECouponScopeModule.APPOINT_SOME_NO.getCode() == scopeModule) {
                        CouponModule couponModule = new CouponModule();
                        couponModule.setCouponNo(no);
                        couponModule.setModuleNo(useModuleNo);
                        int countByDto = couponModuleDaoImpl.countByDto(couponModule);
                        if (ECouponScopeModule.APPOINT_SOME_YES.getCode() == scopeModule && countByDto < 1) {
                            userCouponVo.setIsEnable(false);
                            continue;
                        } else if (ECouponScopeModule.APPOINT_SOME_NO.getCode() == scopeModule && countByDto > 0) {
                            userCouponVo.setIsEnable(false);
                            continue;
                        }
                    }
                    Integer scopeStore = coupon.getScopeStore();
                    if (ECouponScopeStore.APPOINT.getCode() == scopeStore
                        && !coupon.getUseStoreNo().equals(useStoreNo)) {
                        userCouponVo.setIsEnable(false);
                        continue;
                    } else if (ECouponScopeStore.APPOINT_SOME_YES.getCode() == scopeStore
                        || ECouponScopeStore.APPOINT_SOME_NO.getCode() == scopeStore) {
                        CouponStore couponStore = new CouponStore();
                        couponStore.setCouponNo(no);
                        couponStore.setStoreNo(useStoreNo);
                        int countByDto = couponStoreDaoImpl.countByDto(couponStore);
                        if (ECouponScopeStore.APPOINT_SOME_YES.getCode() == scopeStore && countByDto < 1) {
                            userCouponVo.setIsEnable(false);
                            continue;
                        } else if (ECouponScopeStore.APPOINT_SOME_NO.getCode() == scopeStore && countByDto > 0) {
                            userCouponVo.setIsEnable(false);
                            continue;
                        }
                    }
                    Integer scopeGoods = coupon.getScopeGoods();
                    if (ECouponScopeGoods.APPOINT.getCode() == scopeGoods) {
                        userCouponVo.setIsEnable(false);
                        continue;
                    } else if (ECouponScopeGoods.APPOINT_SOME_YES.getCode() == scopeGoods
                        || ECouponScopeGoods.APPOINT_SOME_NO.getCode() == scopeGoods) {
                        CouponGoodsVo couponGoods = new CouponGoodsVo();
                        couponGoods.setCouponNo(no);
                        couponGoods.setCouponUseGoodss(couponUseGoodss);
                        int countByDto = couponGoodsDaoImpl.countCoupon(couponGoods);
                        if (ECouponScopeGoods.APPOINT_SOME_YES.getCode() == scopeGoods
                            && countByDto < couponUseGoodss.size()) {
                            userCouponVo.setIsEnable(false);
                            continue;
                        } else if (ECouponScopeGoods.APPOINT_SOME_NO.getCode() == scopeGoods && countByDto > 0) {
                            userCouponVo.setIsEnable(false);
                            continue;
                        }
                    }
                } else if (typeScope == ECouponTypeScope.APPOINT_MODULE.getCode()) {
                    if (!coupon.getUseModuleNo().equals(useModuleNo)) {
                        userCouponVo.setIsEnable(false);
                        continue;
                    }
                } else if (typeScope == ECouponTypeScope.APPOINT_STORE.getCode()) {
                    if (!coupon.getUseStoreNo().equals(useStoreNo)) {
                        userCouponVo.setIsEnable(false);
                        continue;
                    }
                } else if (typeScope == ECouponTypeScope.APPOINT_GOODS.getCode()) {
                    userCouponVo.setIsEnable(false);
                    continue;
                }
                userCouponVo.setIsEnable(true);
            }
        }
        return list;
    }

    /**
     * 根据对象统计数量
     * 
     * @param couponUse
     * @return
     */
    @Override
    public int countListByDto(CouponUseParam couponUse) {
        return userCouponDaoImpl.countListByDto(couponUse);
    }

    /**
     * 根据对象统计数量
     * 
     * @param couponUse
     * @return
     */
    @Override
    public int countListShoppingByDto(CouponUseParam couponUse) {
        return userCouponDaoImpl.countListShoppingByDto(couponUse);
    }

    /**
     * 获取不可用优惠券
     * 
     * @param couponUse
     * @return
     */
    @Override
    public List<UserCouponVo> listNo(CouponUseParam couponUse) {
        return userCouponDaoImpl.listNo(couponUse);
    }

    /**
     * 修改优惠券状态
     * 
     * @param userCoupon
     * @return
     * @throws SQLException
     */
    @Override
    public int updateStatus(UserCoupon userCoupon) {
        int updateStatusGo = 0;

        if (userCoupon.getStatus() == EUserCouponStatus.RECYCLE.getCode()) {
            synchronized (Lock.UPDATE_COUPON_NUMBER) {
                updateStatusGo = userCouponServiceImpl.updateStatusGo(userCoupon);
            }
        } else {
            updateStatusGo = userCouponServiceImpl.updateStatusGoNo(userCoupon);
        }

        return updateStatusGo;
    }

    public int updateStatusGoNo(UserCoupon userCoupon) {
        UserCoupon findById = userCouponDaoImpl.findById(userCoupon.getId());
        if (StringUtil.isBlankObject(findById)) {
            return 0;
        }

        if (findById.getStatus() == EUserCouponStatus.GET_NO.getCode()) {
            throw new TransException("优惠券还未领取,不能修改状态");
        }
        if (findById.getStatus() == EUserCouponStatus.RECYCLE.getCode()) {
            throw new TransException("优惠券已收回,不能修改状态");
        }

        return userCouponDaoImpl.updateById(userCoupon);
    }

    @Transactional
    public int updateStatusGo(UserCoupon userCoupon) {
        UserCoupon findById = userCouponDaoImpl.findById(userCoupon.getId());
        if (StringUtil.isBlankObject(findById)) {
            return 0;
        }

        if (findById.getStatus() == EUserCouponStatus.GET_NO.getCode()) {
            throw new TransException("优惠券还未领取,不能修改状态");
        }
        if (findById.getStatus() == EUserCouponStatus.RECYCLE.getCode()) {
            throw new TransException("优惠券已收回,不能修改状态");
        }

        int updatePartialById = userCouponDaoImpl.updateById(userCoupon);
        if (updatePartialById < 1) {
            throw new TransException("修改失败，请重试！");
        }

        Coupon findByNo = couponDaoImpl.findByNo(findById.getCouponNo());
        if (StringUtil.isBlankObject(findByNo)) {
            return updatePartialById;
        }
        Coupon coupon = new Coupon();
        coupon.setNo(findByNo.getNo());
        coupon.setNumber(findByNo.getNumber() - 1);
        int updateByNo = couponDaoImpl.updateByNo(coupon);
        if (updateByNo != updatePartialById) {
            throw new TransException("修改失败，请重试！");
        }

        return updatePartialById;
    }

    /**
     * 关闭已结束的优惠券
     * 
     * @param userCoupon
     * @return
     */
    @Override
    public int updateStatusToEnd(UserCouponVo userCoupon) {
        return userCouponDaoImpl.updateStatusToEnd(userCoupon);
    }

    /**
     * 用户首页统计
     * 
     * @return
     */
    @Override
    public Map<String, Integer> countUser(UserCouponVo userCoupon) {
        return userCouponDaoImpl.countUser(userCoupon);
    }

}